今天要來介紹另一個React內建的元件<StrictMode />
,目的是幫助我們可以即早發現bugs即早治療。
使用方式就是將<StrictMode>
元件包在其他元件的外層,在內層的所有其他所有元件都是這個嚴格模式的範圍,沒有例外。
<StrictMode>
<Component />
</StrictMode>
在<StrictMode>
底下的元件會有以下幾個行為,這些行為只有在開發模式的時候才會有,打包過後的production是不會有任何的影響的**。**
元件會渲染兩次,也就是說除了原本的元件渲染外會多一次的渲染,用來檢查元件是否有因為沒有pure(同樣的狀態與props會得到相同的結果)而產生的bugs。因為整個元件會渲染兩次所以包含在內的useState set function、useEffect、useLayoutEffect、useMemo和useReducer等的地方傳入的函式也會跟著呼叫兩次。
像是如果直接修改陣列的值,而不是複製一個陣列出來修改,重複執行兩次就會有不同的結果。如下的範例items就會多push一個同樣id的item,這樣結果就pure了。
export default function StoryTray({ stories }) {
const items = stories;
items.push({ id: 'create', label: 'Create Story' });
return (
<ul>
{items.map(story => (
<li key={story.id}>
{story.label}
</li>
))}
</ul>
);
}
也可以幫助發現在useEffect忘記在clean up function清除一些內容的bug。在官網的另個範例裡,因為沒有清除連線,在每次重新連線就會建立一個新的空間(如果這是實際的應用程式的話),這樣一直建立新的連線對於資源式多餘的使用。
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
}, [roomId]);
官方的建議是可以將<StrictMode>
包在跟元件,讓整個專案都是嚴格模式。
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App /> // App底下的所有元件都會是嚴格模式
</StrictMode>
);
但是,如果有某些元件不想要使用嚴格模式,可以將<StrictMode>
往下移動到別的層級使用,像是下面這個範例在<StrictMode>
外的<Header />
和<Footer />
都不會啟用嚴格模式。
import { StrictMode } from 'react';
function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}
https://react.dev/reference/react/StrictMode